package com.demo;

import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.junit.Before;
import org.junit.Test;

public class ActivitiTest03{
	
	RepositoryService repositoryService = null;
	
	RuntimeService runtimeService = null;
	
	TaskService taskService = null;
	
	@Before
	public void setUp() throws Exception{
		// 创建流程引擎对象
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		// 获取repositoryService
		repositoryService = processEngine.getRepositoryService();
		runtimeService = processEngine.getRuntimeService();
		taskService = processEngine.getTaskService();
	}
	
	/*
	 * 部署流程
	 */
	@Test
	public void deployProcess1(){
		// 创建部署对象
		DeploymentBuilder deploymentBuilder =repositoryService.createDeployment();
		// 加载流程的配置文件和图片
		deploymentBuilder.addClasspathResource("activiti_test01.bpmn")
							.addClasspathResource("activiti_test01.png");
		// 部署			 
		deploymentBuilder.deploy();
	}
	
	/*
	 * 部署流程
	 */
	@Test
	public void deployProcessAddNameAndCategory(){
		// 创建部署对象
		DeploymentBuilder deploymentBuilder =repositoryService.createDeployment();
		// 加载流程的配置文件和图片
		deploymentBuilder.name("请假流程").category("请假类").addClasspathResource("activiti_test01.bpmn")
							.addClasspathResource("activiti_test01.png");
		// 部署			 
		deploymentBuilder.deploy();
	}
	
	/*
	 * 通过zip压缩文件部署流程,zip里包含.bpmn和.png,只是进行压缩
	 */
	@Test
	public void deployProcessByZip(){
		// 创建部署对象
		DeploymentBuilder deploymentBuilder =repositoryService.createDeployment();
		// 加载流程的配置文件和图片
		InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("activitiFile.zip");
		ZipInputStream zipInput = new ZipInputStream(inputStream);
		deploymentBuilder.addZipInputStream(zipInput)
			.name("请假流程")
			.category("请假类");
		
		// 部署			 
		deploymentBuilder.deploy();
	}
	
	/*
	 * 删除流程部署
	 */
	@Test
	public void deleteActivitiDeploy(){
		// act_re_deployment流程部署表的主键id
		String deploymentId = "801";
		// 如果流程已经启动，会报错
		repositoryService.deleteDeployment(deploymentId);
		
		String deploymentId1 = "701";
		//第二个参数是true级联删除，流程启动了有数据，也能删除，false,有数据会报错
		repositoryService.deleteDeployment(deploymentId1, true);
	}
	
	/*
	 * 启动流程
	 */
	@Test
	public void startProcess(){
		/* 启动流程，根据流程定义的key，如果相同的流程定义有多个，那么启动version最高的那个。
		 * 如果想启用其他版本，根据流程定义的id（act_re_procdef表的id，主键）
		 * 如果key相同，做第二次部署会在原有的key的流程上做版本的累加
		 */
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leaveProcess");
		String processInstanceId = processInstance.getProcessInstanceId();
		String activityId = processInstance.getActivityId();
		String definitionId = processInstance.getProcessDefinitionId();
		System.out.println("流程实例id:" + processInstanceId);
		System.out.println("正在活动的节点:" + activityId);
		System.out.println("流程定义id:" + definitionId);	
	}
	
	/*
	 *查询流程实例对象 
	 */
	@Test
	public void queryProcessInstance(){
		String processDefinitionKey = "leaveProcess";
		// 创建流程实例查询对象
		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
		
		List<ProcessInstance> list = processInstanceQuery.processDefinitionKey(processDefinitionKey)
				.orderByProcessDefinitionKey()
				.desc()
				.list();
		for (ProcessInstance processInstance : list) {
			System.out.println("流程实例id:" + processInstance.getProcessInstanceId());
			System.out.println("正在活动的节点:" + processInstance.getActivityId());
			System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
		}
		
		// 如果能确定流程定义的key是唯一的，则调用用singleResult()。不唯一的话会报错！！！！
		ProcessInstance processInstance1 = processInstanceQuery.processDefinitionKey(processDefinitionKey)
				.singleResult();
		
		System.out.println("流程实例id:" + processInstance1.getProcessInstanceId());
		System.out.println("正在活动的节点:" + processInstance1.getActivityId());
		System.out.println("流程定义id:" + processInstance1.getProcessDefinitionId());
	}
	
	/*
	 * 查询流程定义1
	 */
	@Test
	public void queryProcessDefinition(){
		String processDefinitionId = "leaveProcess:4:304";
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionId(processDefinitionId).singleResult();
		String id = processDefinition.getId();
		String key = processDefinition.getKey();
		String name = processDefinition.getName();
		System.out.println(id);
		System.out.println(key);
		System.out.println(name);
	}
	
	/*
	 * 查询流程定义2
	 */
	@Test
	public void queryProcessDefinition1(){
		String processDefinitionKey = "leaveProcess";
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		
		List<ProcessDefinition> processDefinitionList = processDefinitionQuery.processDefinitionKey(processDefinitionKey)
				.orderByProcessDefinitionKey()
				.desc().list();
		for (ProcessDefinition processDefinition : processDefinitionList) {
			String id = processDefinition.getId();
			String key = processDefinition.getKey();
			String name = processDefinition.getName();
			System.out.println(id);
			System.out.println(key);
			System.out.println(name);
		}		
	}	
}